{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Title: #Flip Columns For Maximum Number of Equal Rows"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difficulty: #Medium"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Category Title: #Algorithms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tag Slug: #array #hash-table #matrix"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Name Translated: #数组 #哈希表 #矩阵"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution Name: maxEqualRowsAfterFlips"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Title: #按列翻转得到最大值等行数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Content:\n",
    "<p>给定&nbsp;<code>m x n</code>&nbsp;矩阵&nbsp;<code>matrix</code>&nbsp;。</p>\n",
    "\n",
    "<p>你可以从中选出任意数量的列并翻转其上的&nbsp;<strong>每个&nbsp;</strong>单元格。（即翻转后，单元格的值从 <code>0</code> 变成 <code>1</code>，或者从 <code>1</code> 变为 <code>0</code> 。）</p>\n",
    "\n",
    "<p>返回 <em>经过一些翻转后，行内所有值都相等的最大行数</em>&nbsp;。</p>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<ol>\n",
    "</ol>\n",
    "\n",
    "<p><strong>示例 1：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>matrix = [[0,1],[1,1]]\n",
    "<strong>输出：</strong>1\n",
    "<strong>解释：</strong>不进行翻转，有 1 行所有值都相等。\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 2：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>matrix = [[0,1],[1,0]]\n",
    "<strong>输出：</strong>2\n",
    "<strong>解释：</strong>翻转第一列的值之后，这两行都由相等的值组成。\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 3：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>matrix = [[0,0,0],[0,0,1],[1,1,0]]\n",
    "<strong>输出：</strong>2\n",
    "<strong>解释：</strong>翻转前两列的值之后，后两行由相等的值组成。</pre>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>提示：</strong></p>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>m == matrix.length</code></li>\n",
    "\t<li><code>n == matrix[i].length</code></li>\n",
    "\t<li><code>1 &lt;= m, n &lt;= 300</code></li>\n",
    "\t<li><code>matrix[i][j] == 0</code> 或&nbsp;<code>1</code></li>\n",
    "</ul>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Description: [flip-columns-for-maximum-number-of-equal-rows](https://leetcode.cn/problems/flip-columns-for-maximum-number-of-equal-rows/description/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solutions: [flip-columns-for-maximum-number-of-equal-rows](https://leetcode.cn/problems/flip-columns-for-maximum-number-of-equal-rows/solutions/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_cases = ['[[0,1],[1,1]]', '[[0,1],[1,0]]', '[[0,0,0],[0,0,1],[1,1,0]]']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        op = dict()\n",
    "        for i in range(len(matrix)):\n",
    "            o1, o2 = '', ''\n",
    "            for j in range(len(matrix[0])):\n",
    "                if matrix[i][j]:\n",
    "                    o1 += '0'\n",
    "                    o2 += '1'\n",
    "                else:\n",
    "                    o1 += '1'\n",
    "                    o2 += '0'\n",
    "            if o1 in op.keys():\n",
    "                op[o1] += 1\n",
    "            elif o2 in op.keys():\n",
    "                op[o2] += 1\n",
    "            else:\n",
    "                op[o1] = 1\n",
    "        return max(op.values())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        count = Counter()\n",
    "        for i in range(m):\n",
    "            tmp = 0\n",
    "            for j in range(n):\n",
    "                tmp = 10*tmp + (matrix[i][j] ^ matrix[i][0])\n",
    "            count[tmp] += 1\n",
    "        return max(count.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        res = 0\n",
    "        cnt = dict()\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "\n",
    "        for i in range(m):\n",
    "            value = 0\n",
    "            for j in range(n):\n",
    "                value = value * 10 + matrix[i][0] ^ matrix[i][j]\n",
    "            if value in cnt:\n",
    "                cnt[value] += 1\n",
    "            else:\n",
    "                cnt[value] = 1\n",
    "            res = max(res, cnt[value])\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        cnt = Counter()\n",
    "        for ma in matrix:\n",
    "            x = y = 0\n",
    "            for num in ma:\n",
    "                x = x*2 + num\n",
    "                y = y*2 + 1-num\n",
    "            cnt[x] += 1\n",
    "            cnt[y] += 1\n",
    "        return max(cnt.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        return max(Counter([reduce(lambda x, y: (x << 1) + (y ^ r[0]), r, 0) for r in matrix]).values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        m=len(matrix)\n",
    "        n=len(matrix[0])\n",
    "        ans=defaultdict(int)\n",
    "        for i in range(m):\n",
    "            s=''\n",
    "            if matrix[i][0]==0:\n",
    "\n",
    "                for j in range(n):\n",
    "                    s+=str(matrix[i][j])\n",
    "            else:\n",
    "                for j in range(n):\n",
    "\n",
    "                    s+=str(1-matrix[i][j])\n",
    "            ans[s]+=1\n",
    "        return max(ans.values())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        count = defaultdict(int)\n",
    "        for i in range(m):\n",
    "            value = 0\n",
    "            for j in range(n):\n",
    "                value = value * 10 + (matrix[i][j] ^ matrix[i][0])\n",
    "            count[value] += 1\n",
    "        return max(count.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        n, m = len(matrix), len(matrix[0])\n",
    "        ans = 0\n",
    "        for i, rs in enumerate(matrix):\n",
    "            cnt = 1\n",
    "            for j, re in enumerate(matrix[i+1:]):\n",
    "                yes = True\n",
    "                for k in range(m):\n",
    "                    if rs[k] != re[k]:\n",
    "                        yes = False\n",
    "                        break\n",
    "                if yes:\n",
    "                    cnt += 1\n",
    "                else:\n",
    "                    yes = True\n",
    "                    for k in range(m):\n",
    "                        if rs[k] == re[k]:\n",
    "                            yes = False\n",
    "                            break\n",
    "                    if yes:\n",
    "                        cnt += 1\n",
    "            ans = max(ans, cnt)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        op = dict()\n",
    "        for i in range(len(matrix)):\n",
    "            o1, o2 = '', ''\n",
    "            for j in range(len(matrix[0])):\n",
    "                if matrix[i][j]:\n",
    "                    o1 += '0'\n",
    "                    o2 += '1'\n",
    "                else:\n",
    "                    o1 += '1'\n",
    "                    o2 += '0'\n",
    "            if o1 in op.keys():\n",
    "                op[o1] += 1\n",
    "            elif o2 in op.keys():\n",
    "                op[o2] += 1\n",
    "            else:\n",
    "                op[o1] = 1\n",
    "        return max(op.values())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        op = dict()\n",
    "        for i in range(len(matrix)):\n",
    "            o1, o2 = '', ''\n",
    "            for j in range(len(matrix[0])):\n",
    "                if matrix[i][j]:\n",
    "                    o1 += '0'\n",
    "                    o2 += '1'\n",
    "                else:\n",
    "                    o1 += '1'\n",
    "                    o2 += '0'\n",
    "            if o1 in op.keys():\n",
    "                op[o1] += 1\n",
    "            elif o2 in op.keys():\n",
    "                op[o2] += 1\n",
    "            else:\n",
    "                op[o1] = 1\n",
    "        return max(op.values())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        ans=0\n",
    "        m,n=len(matrix),len(matrix[0])\n",
    "        for r in range(m):\n",
    "            c=1\n",
    "            for r1 in range(m):\n",
    "                if r!=r1:\n",
    "                    c+=matrix[r]==matrix[r1] or all(matrix[r1][i]!=matrix[r][i] for i in range(n))\n",
    "                    #print(c)\n",
    "            ans=max(ans,c)\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "       # 经过翻转某些列后，求满足行内所有值都相等的行的总和最大值\n",
    "       # 寻找格式匹配的最大个数 -- 1001 与 1001&0110匹配\n",
    "        m,n = len(matrix),len(matrix[0])\n",
    "        mask = (1<<n)-1\n",
    "        mp = defaultdict(int)\n",
    "        count = 0\n",
    "        for i in range(m):\n",
    "            strs = \"\".join(list(map(str,matrix[i])))\n",
    "            value = int(\"0b\"+strs,2) # 二进制对应的十进制值\n",
    "            # print(value,value^(mask))\n",
    "            if value^(mask) in mp:\n",
    "                mp[value^(mask)] += 1\n",
    "                count = max(count,mp[value^(mask)])\n",
    "            else:\n",
    "                mp[value] += 1\n",
    "                count = max(count,mp[value])\n",
    "        return count "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        n, m = len(matrix), len(matrix[0])\n",
    "        cnt = Counter()\n",
    "        for i in range(n):\n",
    "            val = 0\n",
    "            for j in range(m):\n",
    "                val = val * 10 + (matrix[i][j] ^ matrix[i][0])\n",
    "            cnt[val] += 1\n",
    "        return max(cnt.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        def get_str(row):\n",
    "            if row[0] == 1: flip_flag = True \n",
    "            else: flip_flag = False\n",
    "            s = ''\n",
    "            for i in row:\n",
    "                if flip_flag:\n",
    "                    s += str(i^1)\n",
    "                else:\n",
    "                    s += str(i)\n",
    "            return s\n",
    "        d = collections.defaultdict(int)\n",
    "        for row in matrix:\n",
    "            d[get_str(row)]+=1\n",
    "        return max(d.values())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        count = Counter()\n",
    "        for i in range(m):\n",
    "            value = 0\n",
    "            for j in range(n):\n",
    "                # 如果 matrix[i][0] 为 1，则对该行元素进行翻转\n",
    "                value = value * 10 + (matrix[i][j] ^ matrix[i][0])\n",
    "            count[value] += 1\n",
    "        return max(count.values())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        count = Counter()\n",
    "        for i in range(m):\n",
    "            value = 0\n",
    "            for j in range(n):\n",
    "                # 如果 matrix[i][0] 为 1，则对该行元素进行翻转\n",
    "                value = value * 10 + (matrix[i][j] ^ matrix[i][0])\n",
    "            count[value] += 1\n",
    "        return max(count.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        def get_str(row):\n",
    "            #相同行或互补行可以变成一样的行\n",
    "            #逆向思维，画样例\n",
    "            if row[0] == 1: flip_flag = True \n",
    "            else: flip_flag = False\n",
    "            s = ''\n",
    "            for i in row:\n",
    "                if flip_flag:\n",
    "                    s += str(i^1)\n",
    "                else:\n",
    "                    s += str(i)\n",
    "            return s\n",
    "        d = collections.defaultdict(int)\n",
    "        for row in matrix:\n",
    "            d[get_str(row)]+=1\n",
    "        return max(d.values())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        return max(Counter([reduce(lambda x, y: (x << 1) + (y ^ r[0]), r, 0) for r in matrix]).values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        for i in matrix:\n",
    "            for j in range(1,len(i)):\n",
    "                i[j] = i[j] ^ i[0]\n",
    "            i[0] = 0\n",
    "        t = Counter([hash(\"\".join([str(j) for j in i])) for i in matrix])\n",
    "        tt = [t[i] for i in t]\n",
    "        print(tt)\n",
    "        return max(tt)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        m,n = len(matrix), len(matrix[0])\n",
    "        mx = int(\"1\" * n, base=2)\n",
    "        cnts = collections.defaultdict(int)\n",
    "        for i in range(m):\n",
    "            num = int(\"\".join(str(j) for j in matrix[i]), base=2)\n",
    "            if num & 1:\n",
    "                num = mx - num \n",
    "\n",
    "            cnts[num] += 1\n",
    "\n",
    "        return max(cnts.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        M = len(matrix)\n",
    "        N = len(matrix[-1])\n",
    "        d = {}\n",
    "        for i in range(M):\n",
    "            if matrix[i][0] == 1:\n",
    "                for j in range(N):\n",
    "                    matrix[i][j] = 1 - matrix[i][j]\n",
    "            # Convert the binary list to a binary string\n",
    "            binary_string = ''.join(str(bit) for bit in matrix[i])\n",
    "            if binary_string not in d:\n",
    "                d[binary_string] = 0\n",
    "            d[binary_string] += 1\n",
    "        max_rows = 0\n",
    "\n",
    "        for k,v in d.items():\n",
    "            max_rows = max(max_rows,v)\n",
    "        \n",
    "        return max_rows\n",
    "\n",
    "            \n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        mx = 0\n",
    "        n, m = len(matrix), len(matrix[0])\n",
    "        for i in range(n):\n",
    "            cnt = 1\n",
    "            for j in range(i+1, n):\n",
    "                yes = True\n",
    "                for x, y in zip(matrix[i], matrix[j]):\n",
    "                    if x != y:\n",
    "                        yes = False\n",
    "                        break\n",
    "                if yes: cnt += 1\n",
    "                \n",
    "                yes = True\n",
    "                for x, y in zip(matrix[i], matrix[j]):\n",
    "                    if x == y:\n",
    "                        yes = False\n",
    "                        break\n",
    "                if yes: cnt += 1\n",
    "            mx = max(mx, cnt)\n",
    "        return mx\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        m,n = len(matrix), len(matrix[0])\n",
    "        max_row = 0\n",
    "\n",
    "        had_rotated = []\n",
    "        for i in range(m):\n",
    "            if i in had_rotated:\n",
    "                continue\n",
    "            for j in range(n):\n",
    "                if matrix[i][j] is 0:\n",
    "                    for k in range(i+1,m):\n",
    "                        matrix[k][j] = 1-matrix[k][j]\n",
    "            # print(\"i\",i)\n",
    "            cur_max = 1\n",
    "            for k in range(i+1,m):\n",
    "                is_zero = True\n",
    "                is_one = True\n",
    "                for j in range(n):\n",
    "                    if  matrix[k][j] is 1:\n",
    "                        is_zero = False\n",
    "                    else:\n",
    "                        is_one = False\n",
    "                    if (not is_zero) and (not is_one):\n",
    "                        break\n",
    "                if is_zero or is_one:\n",
    "                    had_rotated.append(k)\n",
    "                    cur_max +=1\n",
    "                    # print(k)\n",
    "            if cur_max>max_row:\n",
    "                max_row = cur_max\n",
    "        return max_row\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "       # 返回行内所有值都相等行的总和最大值\n",
    "       # 寻找格式匹配的最大个数 -- 1001 与 1001&0110匹配\n",
    "\n",
    "        m,n = len(matrix),len(matrix[0])\n",
    "        mask = (1<<n)-1\n",
    "        mp = defaultdict(int)\n",
    "        count = 0\n",
    "        for i in range(m):\n",
    "            strs = \"\".join(list(map(str,matrix[i])))\n",
    "            value = int(\"0b\"+strs,2)\n",
    "            print(value,value^(mask))\n",
    "            if value^(mask) in mp:\n",
    "                mp[value^(mask)] += 1\n",
    "                count = max(count,mp[value^(mask)])\n",
    "            else:\n",
    "                mp[value] += 1\n",
    "                count = max(count,mp[value])\n",
    "        return count "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\r\n",
    "        m, n = len(matrix), len(matrix[0])\r\n",
    "        res = 0\r\n",
    "        for i in range(m):\r\n",
    "            cnt = 0\r\n",
    "            for j in range(m):\r\n",
    "                if matrix[i] == matrix[j] or matrix[i] == [1 - x for x in matrix[j]]:\r\n",
    "                    cnt += 1\r\n",
    "            res = max(res, cnt)\r\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "       # 经过翻转某些列后，求满足行内所有值都相等的行的总和最大值\n",
    "       # 寻找格式匹配的最大个数 -- 1001 与 1001&0110匹配\n",
    "        m,n = len(matrix),len(matrix[0])\n",
    "        mask = (1<<n)-1\n",
    "        mp = defaultdict(int)\n",
    "        count = 0\n",
    "        for i in range(m):\n",
    "            strs = \"\".join(list(map(str,matrix[i])))\n",
    "            value = int(\"0b\"+strs,2)\n",
    "            print(value,value^(mask))\n",
    "            if value^(mask) in mp:\n",
    "                mp[value^(mask)] += 1\n",
    "                count = max(count,mp[value^(mask)])\n",
    "            else:\n",
    "                mp[value] += 1\n",
    "                count = max(count,mp[value])\n",
    "        return count "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        count = Counter()\n",
    "        for i in range(m):\n",
    "            value = 0\n",
    "            for j in range(n):\n",
    "                # 如果 matrix[i][0] 为 1，则对该行元素进行翻转\n",
    "                value = value * 10 + (matrix[i][j] ^ matrix[i][0])\n",
    "            count[value] += 1\n",
    "        return max(count.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        return max(Counter([reduce(lambda x, y: (x << 1) + (y ^ r[0]), r, 0) for r in matrix]).values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    # * 哈希\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        count = Counter()\n",
    "        for i in range(m):\n",
    "            value = 0\n",
    "            for j in range(n):\n",
    "                # 如果 matrix[i][0] 为 1，则对该行元素进行翻转\n",
    "                value = value * 10 + (matrix[i][j] ^ matrix[i][0])\n",
    "\n",
    "            count[value] += 1\n",
    "\n",
    "        return max(count.values())\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        m=len(matrix)\n",
    "        n=len(matrix[0])\n",
    "        ans=defaultdict(int)\n",
    "        for i in range(m):\n",
    "            s=''\n",
    "            p=''\n",
    "            for j in range(n):\n",
    "                s+=str(matrix[i][j])\n",
    "                p+=str(1-matrix[i][j])\n",
    "            ans[s]+=1\n",
    "            ans[p]+=1\n",
    "        return max(ans.values())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        v = []\n",
    "        for x in matrix:\n",
    "            x = ''.join(map(str, x))\n",
    "            v.append(x)\n",
    "            v.append(x.replace('0', '2').replace('1', '0').replace('2', '1'))\n",
    "            \n",
    "        return Counter(v).most_common(1)[0][1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        return Counter(''.join(str(x ^ line[0]) for x in line) for line in matrix).most_common(1)[0][1]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        m = len(matrix)\n",
    "        n = len(matrix[0])\n",
    "\n",
    "        record = []\n",
    "\n",
    "        for i in range(n):\n",
    "            if matrix[0][i]==0:\n",
    "                record.append(0)\n",
    "            else:\n",
    "                record.append(1)\n",
    "                matrix[0][i] = 0\n",
    "\n",
    "        for i in range(n):\n",
    "            for j in range(1,m):\n",
    "                if record[i] ==1:\n",
    "                    matrix[j][i] = 1 - matrix[j][i]\n",
    "\n",
    "        time = 0\n",
    "        d = {}\n",
    "        \n",
    "        for j in range(m):\n",
    "            s = \"\"\n",
    "            s2 = \"\"\n",
    "            for i in range(n):\n",
    "                s = s+str(matrix[j][i]);\n",
    "                s2 = s2+str(1-matrix[j][i]);\n",
    "\n",
    "            if s in d:\n",
    "                d[s] = d[s]+1\n",
    "            else:\n",
    "                d[s]=1\n",
    "\n",
    "            if s2 in d:\n",
    "                d[s2] = d[s2]+1\n",
    "            else:\n",
    "                d[s2]=1\n",
    "\n",
    "            if d[s] > time:\n",
    "                time=d[s]\n",
    "            \n",
    "            if d[s2] > time:\n",
    "                time=d[s2]\n",
    "        \n",
    "        # print(record)\n",
    "        return time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        m,n = len(matrix),len(matrix[0])\n",
    "        for i in range(m):\n",
    "            if matrix[i][0]:\n",
    "                newrow = [0 if it else 1 for it in matrix[i]]\n",
    "                matrix[i] = newrow\n",
    "        # print(matrix)\n",
    "        dic = {}\n",
    "        for row in matrix:\n",
    "            dic[tuple(row)] = dic.get(tuple(row),0) + 1\n",
    "        return max(dic.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        cnt = Counter()\n",
    "        for row in matrix:\n",
    "            if row[0]:\n",
    "                row = [1-num for num in row]\n",
    "            cnt[tuple(row)] += 1\n",
    "        return max(cnt.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        doc = defaultdict(int)\n",
    "        for row in matrix:\n",
    "            if row[0]:\n",
    "                for i in range(len(row)):\n",
    "                    row[i] = (row[i] + 1) % 2\n",
    "            doc[tuple(row)] += 1\n",
    "        return max(doc.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        ans=Counter()\n",
    "        for row in matrix:\n",
    "            if row[0]:\n",
    "                for i in range(len(row)):\n",
    "                    row[i]^=1\n",
    "            ans[tuple(row)]+=1\n",
    "        return max(ans.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        for i, row in enumerate(matrix):\n",
    "            if row[0] == 1:\n",
    "                matrix[i] = [row[j]^1 for j in range(len(row))]\n",
    "        count = Counter(tuple(row) for row in matrix)\n",
    "        return max(count.values())\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        count = Counter()\n",
    "        for i in range(m):\n",
    "            value =[]\n",
    "            for j in range(n):\n",
    "                # 如果 matrix[i][0] 为 1，则对该行元素进行翻转\n",
    "                value.append(matrix[i][j] ^ matrix[i][0])\n",
    "            \n",
    "            count[tuple(value)] += 1\n",
    "        return max(count.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        # 转化为竖列数字\n",
    "        count = collections.Counter()\n",
    "        for row in matrix:\n",
    "            if row[0]==0:\n",
    "                count[tuple(row)] += 1\n",
    "            else:\n",
    "                c = [i^1 for i in row]\n",
    "                count[tuple(c)] += 1\n",
    "        return max(count.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        cnt = defaultdict(int)\n",
    "        for row in matrix:\n",
    "            if row[0]:\n",
    "                for j in range(len(row)):\n",
    "                    row[j] ^= 1\n",
    "            cnt[tuple(row)] += 1\n",
    "        return max(cnt.values())\n",
    "                    \n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        cnt = Counter()\n",
    "        for row in matrix:\n",
    "            if row[0]:  # 翻转第一个数为 1 的行\n",
    "                for j in range(len(row)):\n",
    "                    row[j] ^= 1\n",
    "            cnt[tuple(row)] += 1\n",
    "        return max(cnt.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        record = Counter()\n",
    "        for row in matrix:\n",
    "            if row[0]:\n",
    "                for j in range(len(row)):\n",
    "                    row[j] = row[j]^1\n",
    "            record[tuple(row)] += 1\n",
    "        return max(record.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        cnt = Counter()\n",
    "        for row in matrix:\n",
    "            if row[0]==0:  # 翻转第一个数为 1 的行\n",
    "                for j in range(len(row)):\n",
    "                    row[j] ^= 1\n",
    "            cnt[tuple(row)] += 1\n",
    "        return max(cnt.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        arr1={}\n",
    "        m,n=len(matrix),len(matrix[0])\n",
    "        if n==0:\n",
    "            return m\n",
    "        for arr in matrix:\n",
    "            m=[1]*n\n",
    "            temp=[m[i]-arr[i] for i in range(n)]\n",
    "            if (tuple(arr) not in arr1) and (tuple(temp) not in arr1):\n",
    "                arr1[tuple(arr)]=1\n",
    "            elif tuple(arr) in arr1:\n",
    "                arr1[tuple(arr)]+=1\n",
    "            else:\n",
    "                arr1[tuple(temp)]+=1\n",
    "        return max(arr1.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        count = Counter()\n",
    "        for row in matrix:\n",
    "            if row[0]:\n",
    "                for i in range(len(row)):\n",
    "                    row[i] ^= 1\n",
    "            count[tuple(row)] += 1\n",
    "        return max(count.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        cnt = Counter()\n",
    "        for row in matrix:\n",
    "            if row[0]:\n",
    "                for j in range(len(row)):\n",
    "                    row[j] ^= 1\n",
    "            cnt[tuple(row)] += 1\n",
    "        return max(cnt.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        cnt = collections.Counter()\n",
    "        for row in matrix:\n",
    "            temp = row if row[0] == 0 else [i ^ 1 for i in row]\n",
    "            cnt[tuple(temp)] += 1\n",
    "        return max(list(cnt.values()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        cnt = Counter()\n",
    "        for row in matrix:\n",
    "            if row[0]:  # 翻转第一个数为 1 的行\n",
    "                for j in range(len(row)):\n",
    "                    row[j] ^= 1\n",
    "            cnt[tuple(row)] += 1\n",
    "        return max(cnt.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        cnt = Counter()\n",
    "        for row in matrix:\n",
    "            t = tuple(row) if row[0] == 0 else tuple(x ^ 1 for x in row)\n",
    "            cnt[t] += 1\n",
    "        return max(cnt.values())\n",
    "\n",
    "# 作者：ylb\n",
    "# 链接：https://leetcode.cn/problems/flip-columns-for-maximum-number-of-equal-rows/solutions/2270337/python3javacgotypescript-yi-ti-yi-jie-ha-gl17/\n",
    "# 来源：力扣（LeetCode）\n",
    "# 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        count = Counter()\n",
    "        for i in range(m):\n",
    "            if matrix[i][0]==1:\n",
    "                for j in range(n):\n",
    "                # 如果 matrix[i][0] 为 1，则对该行元素进行翻转\n",
    "                    matrix[i][j] ^= 1\n",
    "            \n",
    "            count[tuple(matrix[i])] += 1\n",
    "        return max(count.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        dic = {}\n",
    "        for line in matrix:\n",
    "            pos0 = []\n",
    "            pos1 = []\n",
    "            for i in range(len(line)):\n",
    "                if line[i] == 0:\n",
    "                    pos0.append(i)\n",
    "                elif line[i] == 1:\n",
    "                    pos1.append(i)\n",
    "            if len(pos0) == 0:\n",
    "                pos0.append(-1)\n",
    "            if len(pos1) == 0:\n",
    "                pos1.append(-1)\n",
    "            pos0 = tuple(pos0)\n",
    "            pos1 = tuple(pos1)\n",
    "            if pos0 not in dic:\n",
    "                dic[pos0] = 1\n",
    "            else:\n",
    "                dic[pos0] += 1\n",
    "            if pos1 not in dic:\n",
    "                dic[pos1] = 1\n",
    "            else:\n",
    "                dic[pos1] += 1\n",
    "\n",
    "        ret = 0\n",
    "        for key,value in dic.items():\n",
    "            ret = max(ret, value)\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        cnt = collections.Counter()\n",
    "        for row in matrix:\n",
    "            t = tuple(row) if row[0] == 0 else tuple(x ^ 1 for x in row)\n",
    "            cnt[t] += 1\n",
    "        return max(cnt.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        cnt = Counter()\n",
    "        for row in matrix:\n",
    "            if row[0]:  # 翻转第一个数为 1 的行\n",
    "                for j in range(len(row)):\n",
    "                    row[j] ^= 1\n",
    "            cnt[tuple(row)] += 1\n",
    "        return max(cnt.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        cnt = Counter()\n",
    "        for row in matrix:\n",
    "            if row[0]:  # 翻转第一个数为 1 的行\n",
    "                for j in range(len(row)):\n",
    "                    row[j] ^= 1\n",
    "            cnt[tuple(row)] += 1\n",
    "        return max(cnt.values())\n",
    "\n",
    "# class Solution:\n",
    "#     def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "\n",
    "#         cnt = Counter();\n",
    "\n",
    "#         for row in matrix:\n",
    "#             # 以 0 开头\n",
    "#             if row[0] == 0:\n",
    "#                 for j in range(len(row)):\n",
    "#                     row[j]^=1\n",
    "#                     cnt[tuple(row)]+=1\n",
    "\n",
    "#         return max(cnt.values())\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        cnt = Counter()\n",
    "        for row in matrix:\n",
    "            if row[0]:  # 翻转第一个数为 1 的行\n",
    "                for j in range(len(row)):\n",
    "                    row[j] ^= 1\n",
    "            cnt[tuple(row)] += 1\n",
    "        return max(cnt.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        zero_dic = {}\n",
    "        tmp_max = 1\n",
    "        for tmp_row in matrix:\n",
    "            tmp_tuple = tuple(tmp_row)\n",
    "            reverse_tuple = tuple( [1-i for i in tmp_tuple] )\n",
    "            if zero_dic.get( tmp_tuple ):\n",
    "                zero_dic[tmp_tuple] += 1\n",
    "                zero_dic[reverse_tuple] += 1\n",
    "                if zero_dic[tmp_tuple ] > tmp_max:\n",
    "                    tmp_max = zero_dic[tmp_tuple ]\n",
    "            else:\n",
    "                zero_dic[tmp_tuple] = 1\n",
    "                zero_dic[reverse_tuple] = 1\n",
    "        return tmp_max"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:\n",
    "        d = collections.defaultdict(int)\n",
    "        for row in matrix:\n",
    "            row1 = [str(x) for x in row]\n",
    "            row2 = [str(1-x) for x in row]\n",
    "            s1 = str(row1)\n",
    "            s2 = str(row2)\n",
    "            d[s1] += 1\n",
    "            d[s2] += 1\n",
    "        items = sorted(d.items(), key = lambda x: x[1], reverse=True)\n",
    "        return items[0][1]\n"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}
